-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[CIR] Add support for common linkage #168613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add support for marking global variables with common linkage.
|
@llvm/pr-subscribers-clangir Author: Andy Kaylor (andykaylor) ChangesAdd support for marking global variables with common linkage. Full diff: https://github.com/llvm/llvm-project/pull/168613.diff 2 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 4a82ea3121b60..b8e51f87d4045 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -883,8 +883,17 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
// FIXME(cir): setLinkage should likely set MLIR's visibility automatically.
gv.setVisibility(getMLIRVisibilityFromCIRLinkage(linkage));
assert(!cir::MissingFeatures::opGlobalDLLImportExport());
- if (linkage == cir::GlobalLinkageKind::CommonLinkage)
- errorNYI(initExpr->getSourceRange(), "common linkage");
+ if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
+ // common vars aren't constant even if declared const.
+ gv.setConstant(false);
+ // Tentative definition of global variables may be initialized with
+ // non-zero null pointers. In this case they should have weak linkage
+ // since common linkage must have zero initializer and must not have
+ // explicit section therefore cannot have non-zero initial value.
+ std::optional<mlir::Attribute> initializer = gv.getInitialValue();
+ if (initializer && !getBuilder().isNullValue(*initializer))
+ gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
+ }
setNonAliasAttributes(vd, gv);
@@ -1238,10 +1247,8 @@ cir::GlobalLinkageKind CIRGenModule::getCIRLinkageForDeclarator(
// linkage.
if (!getLangOpts().CPlusPlus && isa<VarDecl>(dd) &&
!isVarDeclStrongDefinition(astContext, *this, cast<VarDecl>(dd),
- getCodeGenOpts().NoCommon)) {
- errorNYI(dd->getBeginLoc(), "common linkage", dd->getDeclKindName());
+ getCodeGenOpts().NoCommon))
return cir::GlobalLinkageKind::CommonLinkage;
- }
// selectany symbols are externally visible, so use weak instead of
// linkonce. MSVC optimizes away references to const selectany globals, so
diff --git a/clang/test/CIR/CodeGen/no-common.c b/clang/test/CIR/CodeGen/no-common.c
new file mode 100644
index 0000000000000..ce4c5fc0b3a33
--- /dev/null
+++ b/clang/test/CIR/CodeGen/no-common.c
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -emit-cir -o %t-default.cir
+// RUN: FileCheck --input-file=%t-default.cir %s -check-prefix=CIR-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fno-common -emit-cir -o %t-no-common.cir
+// RUN: FileCheck --input-file=%t-no-common.cir %s -check-prefix=CIR-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fcommon -emit-cir -o %t-common.cir
+// RUN: FileCheck --input-file=%t-common.cir %s -check-prefix=CIR-COMMON
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -emit-llvm -o %t-default-cir.ll
+// RUN: FileCheck --input-file=%t-default-cir.ll %s -check-prefix=LLVM-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fno-common -emit-llvm -o %t-no-common-cir.ll
+// RUN: FileCheck --input-file=%t-no-common-cir.ll %s -check-prefix=LLVM-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fcommon -emit-llvm -o %t-common-cir.ll
+// RUN: FileCheck --input-file=%t-common-cir.ll %s -check-prefix=LLVM-COMMON
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o %t-default.ll
+// RUN: FileCheck --input-file=%t-default.ll %s -check-prefix=OGCG-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -fno-common -emit-llvm -o %t-no-common.ll
+// RUN: FileCheck --input-file=%t-no-common.ll %s -check-prefix=OGCG-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -fcommon -emit-llvm -o %t-common.ll
+// RUN: FileCheck --input-file=%t-common.ll %s -check-prefix=OGCG-COMMON
+
+const int a = 42;
+// CIR-DEFAULT: cir.global constant external @a = #cir.int<42>
+// LLVM-DEFAULT: @a = constant i32 42
+// OGCG-DEFAULT: @a = constant i32 42
+
+// CIR-COMMON: cir.global constant external @a
+// LLVM-COMMON: @a = constant i32 42
+// OGCG-COMMON: @a = constant i32 42
+
+const int b __attribute__((common)) = 42;
+// CIR-DEFAULT: cir.global constant external @b = #cir.int<42>
+// LLVM-DEFAULT: @b = constant i32 42
+// OGCG-DEFAULT: @b = constant i32 42
+
+// CIR-COMMON: cir.global constant external @b = #cir.int<42>
+// LLVM-COMMON: @b = constant i32 42
+// OGCG-COMMON: @b = constant i32 42
+
+const int c __attribute__((nocommon)) = 42;
+// CIR-DEFAULT: cir.global constant external @c = #cir.int<42>
+// LLVM-DEFAULT: @c = constant i32 42
+// OGCG-DEFAULT: @c = constant i32 42
+
+// CIR-COMMON: cir.global constant external @c = #cir.int<42>
+// LLVM-COMMON: @c = constant i32 42
+// OGCG-COMMON: @c = constant i32 42
+
+int d = 11;
+// CIR-DEFAULT: cir.global external @d = #cir.int<11>
+// LLVM-DEFAULT: @d = global i32 11
+// OGCG-DEFAULT: @d = global i32 11
+
+// CIR-COMMON: cir.global external @d = #cir.int<11>
+// LLVM-COMMON: @d = global i32 11
+// OGCG-COMMON: @d = global i32 11
+
+int e;
+// CIR-DEFAULT: cir.global external @e = #cir.int<0>
+// LLVM-DEFAULT: @e = global i32 0
+// OGCG-DEFAULT: @e = global i32 0
+
+// CIR-COMMON: cir.global common @e = #cir.int<0>
+// LLVM-COMMON: @e = common global i32 0
+// OGCG-COMMON: @e = common global i32 0
+
+
+int f __attribute__((common));
+// CIR-DEFAULT: cir.global common @f = #cir.int<0>
+// LLVM-DEFAULT: @f = common global i32 0
+// OGCG-DEFAULT: @f = common global i32 0
+
+// CIR-COMMON: cir.global common @f
+// LLVM-COMMON: @f = common global i32 0
+// OGCG-COMMON: @f = common global i32 0
+
+int g __attribute__((nocommon));
+// CIR-DEFAULT: cir.global external @g = #cir.int<0>
+// LLVM-DEFAULT: @g = global i32
+// OGCG-DEFAULT: @g = global i32 0
+
+// CIR-COMMON: cir.global external @g = #cir.int<0>
+// LLVM-COMMON: @g = global i32 0
+// OGCG-COMMON: @g = global i32 0
+
+const int h;
+// CIR-DEFAULT: cir.global constant external @h = #cir.int<0>
+// LLVM-DEFAULT: @h = constant i32
+// OGCG-DEFAULT: @h = constant i32 0
+
+// CIR-COMMON: cir.global common @h = #cir.int<0>
+// LLVM-COMMON: @h = common global i32 0
+// OGCG-COMMON: @h = common global i32 0
+
+typedef void* (*fn_t)(long a, long b, char *f, int c);
+fn_t ABC __attribute__ ((nocommon));
+// CIR-DEFAULT: cir.global external @ABC = #cir.ptr<null>
+// LLVM-DEFAULT: @ABC = global ptr null
+// OGCG-DEFAULT: @ABC = global ptr null
+
+// CIR-COMMON: cir.global external @ABC = #cir.ptr<null>
+// LLVM-COMMON: @ABC = global ptr null
+// OGCG-COMMON: @ABC = global ptr null
|
|
@llvm/pr-subscribers-clang Author: Andy Kaylor (andykaylor) ChangesAdd support for marking global variables with common linkage. Full diff: https://github.com/llvm/llvm-project/pull/168613.diff 2 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 4a82ea3121b60..b8e51f87d4045 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -883,8 +883,17 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
// FIXME(cir): setLinkage should likely set MLIR's visibility automatically.
gv.setVisibility(getMLIRVisibilityFromCIRLinkage(linkage));
assert(!cir::MissingFeatures::opGlobalDLLImportExport());
- if (linkage == cir::GlobalLinkageKind::CommonLinkage)
- errorNYI(initExpr->getSourceRange(), "common linkage");
+ if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
+ // common vars aren't constant even if declared const.
+ gv.setConstant(false);
+ // Tentative definition of global variables may be initialized with
+ // non-zero null pointers. In this case they should have weak linkage
+ // since common linkage must have zero initializer and must not have
+ // explicit section therefore cannot have non-zero initial value.
+ std::optional<mlir::Attribute> initializer = gv.getInitialValue();
+ if (initializer && !getBuilder().isNullValue(*initializer))
+ gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
+ }
setNonAliasAttributes(vd, gv);
@@ -1238,10 +1247,8 @@ cir::GlobalLinkageKind CIRGenModule::getCIRLinkageForDeclarator(
// linkage.
if (!getLangOpts().CPlusPlus && isa<VarDecl>(dd) &&
!isVarDeclStrongDefinition(astContext, *this, cast<VarDecl>(dd),
- getCodeGenOpts().NoCommon)) {
- errorNYI(dd->getBeginLoc(), "common linkage", dd->getDeclKindName());
+ getCodeGenOpts().NoCommon))
return cir::GlobalLinkageKind::CommonLinkage;
- }
// selectany symbols are externally visible, so use weak instead of
// linkonce. MSVC optimizes away references to const selectany globals, so
diff --git a/clang/test/CIR/CodeGen/no-common.c b/clang/test/CIR/CodeGen/no-common.c
new file mode 100644
index 0000000000000..ce4c5fc0b3a33
--- /dev/null
+++ b/clang/test/CIR/CodeGen/no-common.c
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -emit-cir -o %t-default.cir
+// RUN: FileCheck --input-file=%t-default.cir %s -check-prefix=CIR-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fno-common -emit-cir -o %t-no-common.cir
+// RUN: FileCheck --input-file=%t-no-common.cir %s -check-prefix=CIR-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fcommon -emit-cir -o %t-common.cir
+// RUN: FileCheck --input-file=%t-common.cir %s -check-prefix=CIR-COMMON
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -emit-llvm -o %t-default-cir.ll
+// RUN: FileCheck --input-file=%t-default-cir.ll %s -check-prefix=LLVM-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fno-common -emit-llvm -o %t-no-common-cir.ll
+// RUN: FileCheck --input-file=%t-no-common-cir.ll %s -check-prefix=LLVM-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir %s -fcommon -emit-llvm -o %t-common-cir.ll
+// RUN: FileCheck --input-file=%t-common-cir.ll %s -check-prefix=LLVM-COMMON
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o %t-default.ll
+// RUN: FileCheck --input-file=%t-default.ll %s -check-prefix=OGCG-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -fno-common -emit-llvm -o %t-no-common.ll
+// RUN: FileCheck --input-file=%t-no-common.ll %s -check-prefix=OGCG-DEFAULT
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -fcommon -emit-llvm -o %t-common.ll
+// RUN: FileCheck --input-file=%t-common.ll %s -check-prefix=OGCG-COMMON
+
+const int a = 42;
+// CIR-DEFAULT: cir.global constant external @a = #cir.int<42>
+// LLVM-DEFAULT: @a = constant i32 42
+// OGCG-DEFAULT: @a = constant i32 42
+
+// CIR-COMMON: cir.global constant external @a
+// LLVM-COMMON: @a = constant i32 42
+// OGCG-COMMON: @a = constant i32 42
+
+const int b __attribute__((common)) = 42;
+// CIR-DEFAULT: cir.global constant external @b = #cir.int<42>
+// LLVM-DEFAULT: @b = constant i32 42
+// OGCG-DEFAULT: @b = constant i32 42
+
+// CIR-COMMON: cir.global constant external @b = #cir.int<42>
+// LLVM-COMMON: @b = constant i32 42
+// OGCG-COMMON: @b = constant i32 42
+
+const int c __attribute__((nocommon)) = 42;
+// CIR-DEFAULT: cir.global constant external @c = #cir.int<42>
+// LLVM-DEFAULT: @c = constant i32 42
+// OGCG-DEFAULT: @c = constant i32 42
+
+// CIR-COMMON: cir.global constant external @c = #cir.int<42>
+// LLVM-COMMON: @c = constant i32 42
+// OGCG-COMMON: @c = constant i32 42
+
+int d = 11;
+// CIR-DEFAULT: cir.global external @d = #cir.int<11>
+// LLVM-DEFAULT: @d = global i32 11
+// OGCG-DEFAULT: @d = global i32 11
+
+// CIR-COMMON: cir.global external @d = #cir.int<11>
+// LLVM-COMMON: @d = global i32 11
+// OGCG-COMMON: @d = global i32 11
+
+int e;
+// CIR-DEFAULT: cir.global external @e = #cir.int<0>
+// LLVM-DEFAULT: @e = global i32 0
+// OGCG-DEFAULT: @e = global i32 0
+
+// CIR-COMMON: cir.global common @e = #cir.int<0>
+// LLVM-COMMON: @e = common global i32 0
+// OGCG-COMMON: @e = common global i32 0
+
+
+int f __attribute__((common));
+// CIR-DEFAULT: cir.global common @f = #cir.int<0>
+// LLVM-DEFAULT: @f = common global i32 0
+// OGCG-DEFAULT: @f = common global i32 0
+
+// CIR-COMMON: cir.global common @f
+// LLVM-COMMON: @f = common global i32 0
+// OGCG-COMMON: @f = common global i32 0
+
+int g __attribute__((nocommon));
+// CIR-DEFAULT: cir.global external @g = #cir.int<0>
+// LLVM-DEFAULT: @g = global i32
+// OGCG-DEFAULT: @g = global i32 0
+
+// CIR-COMMON: cir.global external @g = #cir.int<0>
+// LLVM-COMMON: @g = global i32 0
+// OGCG-COMMON: @g = global i32 0
+
+const int h;
+// CIR-DEFAULT: cir.global constant external @h = #cir.int<0>
+// LLVM-DEFAULT: @h = constant i32
+// OGCG-DEFAULT: @h = constant i32 0
+
+// CIR-COMMON: cir.global common @h = #cir.int<0>
+// LLVM-COMMON: @h = common global i32 0
+// OGCG-COMMON: @h = common global i32 0
+
+typedef void* (*fn_t)(long a, long b, char *f, int c);
+fn_t ABC __attribute__ ((nocommon));
+// CIR-DEFAULT: cir.global external @ABC = #cir.ptr<null>
+// LLVM-DEFAULT: @ABC = global ptr null
+// OGCG-DEFAULT: @ABC = global ptr null
+
+// CIR-COMMON: cir.global external @ABC = #cir.ptr<null>
+// LLVM-COMMON: @ABC = global ptr null
+// OGCG-COMMON: @ABC = global ptr null
|
| // explicit section therefore cannot have non-zero initial value. | ||
| std::optional<mlir::Attribute> initializer = gv.getInitialValue(); | ||
| if (initializer && !getBuilder().isNullValue(*initializer)) | ||
| gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only test case I could find that reaches this requires OpenCL and AMDGCN support, but I think the code is straightforward enough to go in ahead of a test case.
Add support for marking global variables with common linkage.